﻿//Copyright (c) Microsoft Corporation
//
//All rights reserved. 
//
//Licensed under the Apache License, Version 2.0 (the ""License""); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. 
//
//See the Apache Version 2.0 License for specific language governing permissions and limitations under the License.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TED.WindowsAzure.Unplugged.Mobile.Sync.File;
using TED.WindowsAzure.Unplugged.Mobile.Sync.Folder;
using TED.WindowsAzure.Unplugged.Mobile.Sync.Storage;
using Windows.Storage;
using Windows.Storage.Streams;

namespace TED.WindowsAzure.Unplugged.Mobile.Tests.Mocks
{
    public class MockLocalFileStorage : ISyncFileStorage
    {
        private ISyncFileStateStorage _stateStorage;

        private List<ISyncFile> _localFiles = new List<ISyncFile>();

        public MockLocalFileStorage(ISyncFileStateStorage stateStorage)
        {
            _stateStorage = stateStorage;

            // add some mock data
            for (int i = 0; i < 5; i++)
            {
                var file = new MockLocalFile(new MockSyncFolder("foo"))
                {
                    FileName = i.ToString(),
                };

                _localFiles.Add(file);
            }

        }

        public async Task<ISyncFile> CreateFileAsync(string name, ISyncFolder folder)
        {
            ISyncFile localFile = new MockLocalFile(folder);
            var fileState = await _stateStorage.LookupAsync(folder.FolderName, name);

            if (fileState != null)
            {
                localFile.ApplyPropertiesFrom(fileState as ISyncFileState);
            }
            else
            {
                localFile.FileName = name;
            }

            return localFile;
        }

        public Task<IRandomAccessStream> OpenReadAsync(ISyncFile instance)
        {
            return Task.Factory.StartNew(() =>
                {
                    return new MockRandomAccessStream() as IRandomAccessStream;
                });
        }

        public Task<IRandomAccessStream> OpenWriteAsync(ISyncFile instance)
        {
            return Task.Factory.StartNew(() =>
            {
                return new MockRandomAccessStream() as IRandomAccessStream;
            });
        }

        public Task DeleteAsync(ISyncFile instance)
        {
            throw new NotImplementedException();
        }

        public async Task InsertAndCommitAsync(ISyncFile instance, IRandomAccessStream source)
        {
            _localFiles.Add(instance);

            var state = await _stateStorage.CreateFileAsync();

            state.ApplyPropertiesFrom(instance);

            await _stateStorage.InsertAsync(state);
        }

        public Task UpdateAndCommitAsync(ISyncFile instance, IRandomAccessStream source)
        {
            throw new NotImplementedException();
        }

        public async Task<IEnumerable<ISyncFile>> ReadAsync(ISyncFolder folder)
        {
            var stateList = await _stateStorage.ReadAsync(folder.FolderName);
            var fileList = new List<ISyncFile>();

            foreach (var s in stateList)
            {
                ISyncFile localFile = new MockLocalFile(folder);
                localFile.ApplyPropertiesFrom(s);
                fileList.Add(localFile);
            }

            return fileList;
        }

        public Task<ISyncFile> LookupAsync(ISyncFolder folder, int id)
        {
            throw new NotImplementedException();
        }

        public Task<IStorageFile> GetInternalStorageFile(ISyncFile instance)
        {
            throw new NotImplementedException();
        }

        public async Task<ISyncFile> LookupAsync(ISyncFolder folder, string name)
        {
            ISyncFile localFile = null;
            var fileState = await _stateStorage.LookupAsync(folder.FolderName, name);

            if (fileState != null)
            {
                localFile = new MockLocalFile(folder);
                localFile.ApplyPropertiesFrom(fileState as ISyncFileState);
            }

            return localFile;
        }

        public async Task TruncateAsync(ISyncFolder folder)
        {
            this._localFiles.Clear();

            await _stateStorage.TruncateAsync(folder.FolderName);
        }

        public Task CommitAsync(ISyncFile instance, ISyncFolder folder)
        {
            throw new NotImplementedException();
        }

        public Task FlushAsync(ISyncFolder folder)
        {
            throw new NotImplementedException();
        }

        public Task CommitAsync(ISyncFile instance)
        {
            throw new NotImplementedException();
        }

        public Task CancelAsync(ISyncFolder folder)
        {
            throw new NotImplementedException();
        }

        public Task UndoAsync(ISyncFile instance)
        {
            throw new NotImplementedException();
        }

        public Task SyncedAsync(ISyncFile instance, SyncFileStatus status)
        {
            throw new NotImplementedException();
        }
    }
}
